/*
 * Utility functions for searching users
 *
 * Copyright 2023 Odin Kroeger.
 *
 * This file is part of suCGI.
 *
 * suCGI is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * suCGI is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General
 * Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with suCGI. If not, see <https://www.gnu.org/licenses/>.
 */

#if !defined(TESTS_UTIL_USER_H)
#define TESTS_UTIL_USER_H

#include <sys/types.h>
#include <pwd.h>

#include "../../attr.h"
#include "types.h"


/* NOLINTBEGIN(bugprone-reserved-identifier,cert-dcl37-c); see attr.h */

#if defined(__GNUC__) && \
    (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) && \
    !defined(__INTEL_COMPILER)
#define _returns_nonnull __attribute__((returns_nonnull))
#else
#define _returns_nonnull
#endif

/* NOLINTEND(bugprone-reserved-identifier,cert-dcl37-c) */


/*
 * Get the primary group of the given user and return it in "group".
 *
 * user_get_group also takes a pointer to an error handling function.
 * If an error occurs, this function is called after clean-up;
 * if that pointer is NULL, error handling is left to the caller.
 * The user not having been found does not count as an error.
 *
 * Return value:
 *      Negative    An error occurred; errno should be set.
 *      Zero        Success.
 *      Positive    No such user.
 */
_write_only(2) _nonnull(2)
int user_get_group(uid_t user, gid_t *group, ErrorFn errh);

/*
 * Search for a non-superuser and return it in "pwd".
 *
 * user_get_regular also takes a pointer to an error handling function.
 * See user_get_group for details. No non-superuser being found does not
 * count as an error.
 *
 * Return value:
 *      Negative    An error occurred; errno should be set.
 *      Zero        A non-superuser was found.
 *      Positive    No non-superuser.
 *
 * Errors:
 *      See setpwent, getpwent, and endpwent.
 *
 * Caveats:
 *      Calls setpwent, getpwent, and endpwent.
 *      Not async-safe.
 */
_write_only(1) _nonnull(1)
int user_get_regular(struct passwd *pwd, ErrorFn errh);

#endif /* !defined(TESTS_UTIL_USER_H) */
